'use strict';

const Package = require('@dou-gong-cli/package');
const log = require('@dou-gong-cli/log');
const path = require('path');
const formatPath = require('@dou-gong-cli/format-path');
const utils = require('@dou-gong-cli/utils');

/** 映射表
 *  命令 ---> pkg名称
 */
const SETTINGS = {
  'init': '@dou-gong-cli/init'
};

/** 缓存 package目录 */
const CACHE_DIR = 'dependencies';

async function exec() {
  let pkg;
  let targetPath = process.env.DG_CLI_TARGET_PATH;
  const homePath = process.env.DG_CLI_HOME_PATH;
  let storeDir = '';

  const cmdObj = arguments[arguments.length - 1];
  const packageName = SETTINGS[cmdObj.name()];
  log.verbose('exec cmd', cmdObj.name());
  log.verbose('exec packageName', packageName);

  const packageVersion = 'latest';

  if (!targetPath) {
    targetPath = formatPath(path.resolve(homePath, CACHE_DIR));
    storeDir = formatPath(path.resolve(targetPath, 'node_modules'));

    pkg = new Package({
      targetPath,
      packageName,
      packageVersion,
      storeDir
    });

    if (await pkg.exists()) {
      await pkg.update();
    } else {
      await pkg.install();
    }
  } else {
    pkg = new Package({
      targetPath,
      packageName,
      packageVersion
    });
  }

  const rootFilePath = pkg.getRootFilePath();
  if (rootFilePath) {
    try {
      // require(rootFilePath)(Array.from(arguments));
      const args = Array.from(arguments);
      const cmd = args[args.length - 1];
      const o = Object.create(null);
      Object.keys(cmd).forEach((key) => {
        if (
          cmd.hasOwnProperty(key) &&
          !key.startsWith('_') &&
          key !== 'parent'
        ) {
          o[key] = cmd[key];
        }
      });
      args[args.length - 1] = o;

      let code = `require('${rootFilePath}').call(null, ${JSON.stringify(
        args
      )})`;

      const child = utils.exec('node', ['-e', code], {
        cwd: process.cwd(),
        stdio: 'inherit'
      });

      child.on('error', (e) => {
        log.error('exec', e.message);
        process.exit(1);
      });

      child.on('exit', (code) => {
        log.verbose(
          `命令执行${code === 0 ? '成功' : '失败'}`,
          `exit code ${code}`
        );
        process.exit(code);
      });
    } catch (error) {
      log.error('exec', error.message);
    }
  }
}

module.exports = exec;
